﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace Acoris.Markdown
{
    /// <summary>
    /// 表示AML节点集合
    /// </summary>
    internal sealed class AMLParseNodeCollection:ICollection<AMLParseNode>
    {
        Collection<AMLParseNode> m_collection = new Collection<AMLParseNode>();

        /// <summary>
        /// 获取当前集合中元素的个数
        /// </summary>
        public int Count => ((ICollection<AMLParseNode>)m_collection).Count;

        /// <summary>
        /// 获取当前集合的只读性
        /// </summary>
        public bool IsReadOnly => ((ICollection<AMLParseNode>)m_collection).IsReadOnly;

        /// <summary>
        /// 将指定的元素添加到集合中
        /// </summary>
        /// <param name="item">指定要添加的元素</param>
        /// <exception cref="ArgumentNullException">添加的对象为空</exception>
        public void Add(AMLParseNode item)
        {
            if(item == null)
            {
                throw new ArgumentNullException();
            }
            m_collection.Add(item);
        }

        /// <summary>
        /// 清空当前集合
        /// </summary>
        public void Clear()
        {
            m_collection.Clear();
        }

        /// <summary>
        /// 返回一个值，该值只是当前集合中是否存在指定的元素
        /// </summary>
        /// <param name="item">要对比的元素</param>
        /// <returns>如果指定的元素存在于当前集合则返回true，否则返回false</returns>
        /// <exception cref="ArgumentNullException">添加的对象为空</exception>
        public bool Contains(AMLParseNode item)
        {
            if (item == null)
            {
                throw new ArgumentNullException();
            }
            return m_collection.Contains(item);
        }

        /// <summary>
        /// 将当前集合元素复制到目标数组
        /// </summary>
        /// <param name="array">目标数组</param>
        /// <param name="arrayIndex">复制操作在目标数组的起始位置</param>
        /// <exception cref="ArgumentNullException">目标数组为空</exception>
        /// <exception cref="IndexOutOfRangeException">目标数组长度不足</exception>
        public void CopyTo(AMLParseNode[] array, int arrayIndex)
        {
            if(array == null)
            {
                throw new ArgumentNullException();
            }

            if(arrayIndex + this.Count > array.Length)
            {
                throw new IndexOutOfRangeException();
            }

            m_collection.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// 返回用于迭代当前集合的枚举数
        /// </summary>
        /// <returns>返回用于迭代当前集合的枚举数</returns>
        public IEnumerator<AMLParseNode> GetEnumerator()
        {
            return m_collection.GetEnumerator();
        }

        /// <summary>
        /// 移除指定元素
        /// </summary>
        /// <param name="item">指定要移除的元素</param>
        /// <returns>如果移除成功则返回true，否则返回false</returns>
        /// <exception cref="ArgumentNullException">添加的对象为空</exception>
        public bool Remove(AMLParseNode item)
        {
            if (item == null)
            {
                throw new ArgumentNullException();
            }
            return m_collection.Remove(item);
        }

        /// <summary>
        /// 返回用于迭代当前集合的枚举数
        /// </summary>
        /// <returns>返回用于迭代当前集合的枚举数</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return m_collection.GetEnumerator();
        }

        /// <summary>
        /// 返回与当前对象等价的字符串形式
        /// </summary>
        /// <returns>返回与当前对象等价的字符串形式</returns>
        public override string ToString()
        {
            return $"count:{Count}";
        }

        /// <summary>
        /// 返回当前对象的等价性
        /// </summary>
        /// <param name="obj">指示要比较的对象</param>
        /// <returns>如果当前实例与目标对象等价则返回true，否则返回false</returns>
        public override bool Equals(object obj)
        {
            if(obj is AMLParseNodeCollection anCollection)
            {
                return anCollection.Equals(this);
            }
            return false;
        }

        /// <summary>
        /// 返回当前实例的哈希值
        /// </summary>
        /// <returns>返回当前实例的哈希值</returns>
        public override int GetHashCode()
        {
            return base.GetHashCode() ^ m_collection.GetHashCode();
        }

        /// <summary>
        /// 获取或设置指定索引位置的元素
        /// </summary>
        /// <param name="index">指定的索引位置</param>
        /// <returns>返回指定索引位置的元素</returns>
        public AMLParseNode this[int index]
        {
            get { return m_collection[index]; }
            set { m_collection[index] = value; }
        }
    }
}
